home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / dbread2.zip / DBREAD.C next >
Text File  |  1992-01-08  |  6KB  |  190 lines

  1. /* Opens a DBF file and gives some information about the structure */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <fcntl.h>
  7. #include <ctype.h>
  8. #include <sys\types.h>
  9. #include <sys\stat.h>
  10. #include <io.h>
  11. #pragma pack(1)
  12.  
  13. /* Some dBASE constants */
  14. #define VERSION "1.0b"
  15. #define MAXFIELDS 255
  16. #define FDASIZE 32
  17. #define DBF_VERSION_MASK 7
  18. #define DB4_MEMO_MASK 8
  19. #define ANY_MEMO_MASK 128
  20.  
  21. /* A function to check for a specified extension in a file name string
  22.    and add it if the extension wasn't found */
  23. void FullName( char *fileName, char *fileExt );
  24.  
  25. /* Define header structure without including field descriptor array,
  26.    see page E-2 of the dBASE IV Language Reference */
  27. struct HEADER {
  28.    unsigned char first_byte;
  29.    unsigned char last_upd_yr;
  30.    unsigned char last_upd_month;
  31.    unsigned char last_upd_day;
  32.    unsigned long num_recs;
  33.    unsigned int head_bytes;
  34.    unsigned int rec_bytes;
  35.    unsigned char reserved_1[2];
  36.    unsigned char incomplete;
  37.    unsigned char is_encrypted;
  38.    unsigned char reserved_for_lan[12];
  39.    unsigned char has_mdx;
  40.    unsigned char reserved_2[3];
  41. } in_header ;
  42.  
  43. /* Define structure for array of field descriptors,
  44.    see page E-3 of the dBASE IV Language Reference */
  45. struct FDA {
  46.    unsigned char field_name[11];
  47.    unsigned char field_type; /* C D F L M N */
  48.    unsigned char reserved1[4];
  49.    unsigned char field_length; /* in binary */
  50.    unsigned char field_decimal; /* in binary */
  51.    unsigned char reserved2[2];
  52.    unsigned char work_area_id;
  53.    unsigned char reserved3[10];
  54.    unsigned char has_tag; /* 01H if has tag in production MDX, 00H if not */
  55. } fd_array[ MAXFIELDS + 1 ] ; /* MAXFIELDS + 1 so that we don't have to deal
  56.                                  with array element 0 */
  57.  
  58. /* String for input file name */
  59. char input_file[256];
  60.  
  61. void main( int argc, char *argv[] )
  62. {
  63.    unsigned int input_handle, x, field_counter;
  64.  
  65.    /* Make sure there was at least one command line argument besides
  66.       program name */
  67.    if( argc < 2 ) {
  68.       printf( "\nDBRead Version %s by Martin R. Leon\n\n"\
  69.          "Missing command line argument.\n"\
  70.          "USAGE:\tDBREAD <DBF file name>\n", VERSION );
  71.       exit(0);
  72.    }
  73.  
  74.    strcpy( input_file, argv[1] );
  75.    FullName( input_file, "DBF" );
  76.  
  77.    /* Open file for read-only in binary mode and make sure there are
  78.       no errors openning it */
  79.    if((input_handle = open(input_file, O_RDONLY | O_BINARY, S_IREAD)) == -1)
  80.    {
  81.       printf( "Unable to open file %s\n", input_file );
  82.       exit( 0 );
  83.    }
  84.  
  85.    /* Read record header to in_header and check for error */
  86.    if( read( input_handle, &in_header, sizeof(in_header) ) == -1 ) {
  87.       printf( "\nError reading header from file!\n" );
  88.       if( close( input_handle ) != 0 )
  89.          printf( "\nError closing file!\n" );
  90.       else
  91.          printf( "\nFile closed!\n" );
  92.       exit(0);
  93.    }
  94.  
  95.    /* Read in field descriptor array.  Read first field descriptor array
  96.       then go into for loop until 0DH is read into the field name. */
  97.    read( input_handle, &fd_array[1], FDASIZE );
  98.    for( field_counter = 1; field_counter <= MAXFIELDS; field_counter++ )
  99.    {
  100.       if( fd_array[ field_counter ].field_name[ 0 ] == 0x0D )
  101.       {
  102.          field_counter--;
  103.          break;
  104.       }
  105.       read( input_handle, &fd_array[field_counter + 1], FDASIZE );
  106.    }
  107.  
  108.    /* Print out header information */
  109.    printf( "\nDatabase name: %s \tDBF version: %d\n"\
  110.       "Any Memo's ?  %c\t\t"\
  111.       "dBASE IV Memo ?  %c\t"\
  112.       "Last Update:  %d/%d/%d\n"\
  113.       "Number of records:  %ld\t"\
  114.       "Encrypted ?  %c\t\t"\
  115.       "MDX ?  %c\n",
  116.       input_file,
  117.       in_header.first_byte & DBF_VERSION_MASK,
  118.       ((in_header.first_byte & ANY_MEMO_MASK) ? 'Y' : 'N' ),
  119.       ((in_header.first_byte & DB4_MEMO_MASK) ? 'Y' : 'N' ),
  120.       in_header.last_upd_month,
  121.       in_header.last_upd_day,
  122.       in_header.last_upd_yr,
  123.       in_header.num_recs,
  124.       ((int)in_header.is_encrypted) ? 'Y' : 'N',
  125.       ((int)in_header.has_mdx) ? 'Y' : 'N' );
  126.  
  127.    /* If encrypted, don't bother trying to read the rest of the structure */
  128.    if( in_header.is_encrypted )
  129.       return;
  130.  
  131.    /* Print out field information */
  132.    printf( "\nField name\tType\tLen\tDec\tMDX\n\n" );
  133.  
  134.    for( x = 1; x <= field_counter; x++ )
  135.       printf( "%-10s\t%c\t%d\t%d\t%c\n",
  136.          fd_array[ x ].field_name,
  137.          fd_array[ x ].field_type,
  138.          fd_array[ x ].field_length,
  139.          fd_array[ x ].field_decimal,
  140.          ((fd_array[ x ].has_tag) ? 'Y' : 'N') );
  141.  
  142.    /* Close file */
  143.    if( close( input_handle ) != 0 )
  144.       printf( "\nError closing file!\n" );
  145.  
  146.    exit( 0 );
  147. }
  148.  
  149.  
  150. /* Adds an extension to a string containing a file name if the specified
  151.    extension isn't already in the string.  String must be larger than the
  152.    combination of the existing string and the extension to be added.
  153.    All done through pointer to original string. */
  154.  
  155. void FullName( char *fileName, char *fileExt )
  156. {
  157.    /* Set ptr to last character before terminator in fiel name */
  158.    char *ptr = fileName + ( strlen( fileName ) - 1 );
  159.  
  160.    /* Check for extension already in name */
  161.    if( strstr( fileName, fileExt ) != NULL )
  162.       return;
  163.  
  164.    /* Extension wasn't found, back up ptr to first non-alpha character,
  165.       stop if we got to beginning of string */
  166.    while( isalpha( (int)*ptr ) )
  167.    {
  168.       if( --ptr == fileName )
  169.          break;
  170.    }
  171.  
  172.    /* If we backed up to a slash, add ".DBF" to the end of the file name
  173.       and return */
  174.    if( *ptr == '\\' )
  175.    {
  176.       fileName = strcat( fileName, ".DBF" );
  177.       return;
  178.    }
  179.  
  180.    /* If we backed up to a period, return without adding extension */
  181.    if( *ptr == '.' )
  182.       return;
  183.  
  184.    /* Add extension, since it wasn't found */
  185.    strcat( fileName, ".DBF" );
  186.    return;
  187. }
  188.  
  189.  
  190.